<?php

// Разрешение/запрет отображения/редактирования поля на форме
define( 'SET_VIEW', 1 );
define( 'SET_EDIT', 2 );

// Номера полей на форме
define( 'BUILD_NAME', 0 );
define( 'BUILD_ADDRESS', 1 );
define( 'BUILD_HIGHT', 2 );
define( 'POYT', 3 );
define( 'SCSR', 4 );
define( 'LOS', 5 );
define( 'CWSR', 6 );
define( 'LOC_TYPE', 7 );
define( 'PERM01_DATE', 8 );
define( 'PERM02_DATE', 9 );
define( 'PERM03_DATE', 10 );
define( 'RENT_DATE', 11 );
define( 'DECL01_DATE', 12 );
define( 'DECL02_DATE', 13 );

class Parcel {
  public $time_multiplier = 86400;
  public $bounce_time = 1;
  public $stage_timeout = array(999999, 30,90,60,30,30,14,14);
  
  function __construct() {
	$tpl = App::me()->tpl;
	
//  Временные интервалы для землеотведения
	if( ( $a = $tpl->getConfigVars('time_multiplier') ) !== '' )	   $this->time_multiplier = $a;
	if( ( $a = $tpl->getConfigVars('bounce_time') ) !== '' )	   $this->bounce_time = $a;
	$this->bounce_time *= $this->time_multiplier;
	
	for( $i=1; $i<8; $i++ ) {
		if( ( $a = $tpl->getConfigVars('stage'.$i.'_timeout') ) !== '' ) $this->stage_timeout[$i] = $a;
		$this->stage_timeout[$i] *= $this->time_multiplier;
	}
  }

  public function select() {
  
    $data = new jqGridData();
    try
    {
// Только зарегистрированные пользователи могут видеть данные
		if( !isset($_SESSION['user_id']) || $_SESSION['user_id'] == 0 )
			throw new Exception(ERR_M::TIMEOUT_ERROR, 999);

// Есть ли права на просмотр чьих либо записей
		$rwd = $_SESSION['priv']->parcel->rwd;
		if( ($rwd & PERM_BITS::READ_ANY) == 0 ) throw new Exception(ERR_M::DATA_ACC_DISABLED, 99);

// Проверяем данные
        $page    = ( isset($_REQUEST["page"]) && $_REQUEST["page"] > 0 ) ? $_REQUEST["page"] : 1;
        $limit    = ( isset($_REQUEST["rows"]) && $_REQUEST["rows"] > 0 ) ? $_REQUEST["rows"] : 1;
        $sidx    = ( isset($_REQUEST["sidx"]) && $_REQUEST["sidx"] != '' ) ? $_REQUEST["sidx"] : 'build_name';
        $sord    = ( isset($_REQUEST["sord"]) && strtolower($_REQUEST["sord"]) == 'desc' ) ? 'DESC' : 'ASC';
        $search    = ( isset($_REQUEST["_search"]) && strtolower($_REQUEST["_search"]) == 'true') ? true : false;
 
// Открываем базу данных
		$db = App::me()->dbOpen();	

// Фильтр
        $whc = array();
        if( $search )
        {

// par_id, par_build_id, build_name, build_address, height

			if(isset($_REQUEST["par_id"]) && is_numeric($_REQUEST["par_id"]) ) {
				$whc[] = "par_id=" . $db->quote($_REQUEST["par_id"]);
		    }
            
            if(isset($_REQUEST["par_build_id"]) && $_REQUEST["par_build_id"] != "") {
		    	$whc[] = "par_build_id=" . $db->quote($_REQUEST["par_build_id"]);
            }

            if(isset($_REQUEST["build_name"]) && $_REQUEST["build_name"] != "") {
		    	$whc[] = "build_name LIKE " . $db->quote("%".$_REQUEST["build_name"]."%");
            }
			
            if(isset($_REQUEST["build_address"]) && $_REQUEST["build_address"] != "") {
		    	$whc[] = "build_address LIKE " . $db->quote("%".$_REQUEST["build_address"]."%");
            }
			
			if(isset($_REQUEST["height"]) && is_numeric($_REQUEST["height"]) ) {
				$whc[] = "height=" . $db->quote($_REQUEST["height"]);
		    }
            
// poyt, scsr, los, cwsr, start_cw, finish_cw

            if(isset($_REQUEST["poyt"]) && $_REQUEST["poyt"] != "") {
				$whc[] = "poyt LIKE " . $db->quote("%".$dt."%");
            }
			
            if(isset($_REQUEST["scsr"]) && ( $dt = Tools::date_to_search_str( $_REQUEST["scsr"] )) != "") {
				$whc[] = "scsr LIKE " . $db->quote("%".$dt."%");
            }
			
            if(isset($_REQUEST["los"]) && ( $dt = Tools::date_to_search_str( $_REQUEST["los"] )) != "") {
				$whc[] = "los LIKE " . $db->quote("%".$dt."%");
            }
			
            if(isset($_REQUEST["cwsr"]) && ( $dt = Tools::date_to_search_str( $_REQUEST["cwsr"] )) != "") {
				$whc[] = "cwsr LIKE " . $db->quote("%".$dt."%");
            }
			
// loctype, perm01_date, perm02_date, perm03_date 

            if(isset($_REQUEST["loctype"]) && is_numeric($_REQUEST["loctype"]) ) {
				$loctype = (int)$_REQUEST["loctype"];
				if( $loctype >= 0 && $loctype < 3 )
					$whc[] = "loctype = " . $db->quote($loctype);
            }
			
            if(isset($_REQUEST["perm01_date"]) && ( $dt = Tools::date_to_search_str( $_REQUEST["perm01_date"] )) != "") {
				$whc[] = "perm01_date LIKE " . $db->quote("%".$dt."%");
            }
			
            if(isset($_REQUEST["perm02_date"]) && ( $dt = Tools::date_to_search_str( $_REQUEST["perm02_date"] )) != "") {
				$whc[] = "perm02_date LIKE " . $db->quote("%".$dt."%");
            }
			
            if(isset($_REQUEST["perm03_date"]) && ( $dt = Tools::date_to_search_str( $_REQUEST["perm03_date"] )) != "") {
				$whc[] = "perm03_date LIKE " . $db->quote("%".$dt."%");
            }
			
// rent, decl01, decl01, par_comment
 
            if(isset($_REQUEST["rent"]) && ( $dt = Tools::date_to_search_str( $_REQUEST["rent"] )) != "") {
				$whc[] = "rent LIKE " . $db->quote("%".$dt."%");
            }
			
            if(isset($_REQUEST["decl01"]) && ( $dt = Tools::date_to_search_str( $_REQUEST["decl01"] )) != "") {
				$whc[] = "decl01 LIKE " . $db->quote("%".$dt."%");
            }
			
            if(isset($_REQUEST["decl02"]) && ( $dt = Tools::date_to_search_str( $_REQUEST["decl02"] )) != "") {
				$whc[] = "decl02 LIKE " . $db->quote("%".$dt."%");
            }
						
            if(isset($_REQUEST["par_comment"]) && $_REQUEST["par_comment"] != "") {
		    	$whc[] = "par_comment LIKE " . $db->quote("%".$_REQUEST["par_comment"]."%");
            }
			
		}

// Фильтр привилегий
		if( $rwd & PERM_BITS::READ_OTH ) $whc[] = '1 = 1';
		elseif( $rwd & PERM_BITS::READ_GRP ) 
			$whc[] = 'par_user_id IN (SELECT user_id FROM users WHERE cat_id = '.$_SESSION['cat_id'].')';
		elseif( $rwd & PERM_BITS::READ_OWN ) $whc[] = 'par_user_id = '.$_SESSION['user_id'];
		else $whc[] = '1 = 0';
		
        $whereclaus = (count($whc) != 0 ) ? " WHERE " . implode(" AND ", $whc) : "";
		unset($whc);
            
// Получаем количество записей с учетом фильтра
        $joins = 
                "INNER JOIN builds ON builds.build_id = parcel.par_build_id";
            
        $sqlreq = "SELECT COUNT(*) AS count FROM parcel ".$joins.$whereclaus;
        $recset = $db->query( $sqlreq );
		$row = $recset->fetch(PDO::FETCH_ASSOC);
		$count = $row['count'];
		$recset->closeCursor();
            
// Пустая таблица
        if ($count == 0)
			throw new Exception(ERR_M::SUCCESS, 0);
            
// Рассчитаем сколько всего страниц займут данные в БД
    	if( $count > 0 && $limit > 0) {
    		$total_pages = ceil($count/$limit);
    	} else {
    		$total_pages = 0;
    	}                  
 
		if ($page > $total_pages) $page=$total_pages;                  
 
		$start = $limit*$page - $limit;                   
		if($start < 0) $start = 0;                  
 
// Формируем запрос
		$sqlreq =   "SELECT par_id, par_build_id, build_name, build_address, height, poyt, scsr, los, cwsr, ".
							"loctype, perm01_date, perm02_date, perm03_date, ".
							"rent, decl01, decl02, par_comment, stage, stage_date ".
					"FROM parcel ".$joins.$whereclaus." ORDER BY ".$sidx." ".$sord.
		            " LIMIT ".$start.", ".$limit;

		$recset = $db->query($sqlreq);                  
 
// Формирование объекта для возврата
        
    	$data->page      = $page;
    	$data->total     = $total_pages;
    	$data->records   = $count;
    		
    // Строки данных для таблицы
		$i = 0;
		while($row = $recset->fetch(PDO::FETCH_ASSOC)) {
		
			$status = 0;

			$bname = preg_replace( '/[^а-яіїa-z0-9]/u', '', mb_strtolower( $row['build_name'], 'UTF-8') );
			$dr = App::me()->basePath. DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'docs' . DIRECTORY_SEPARATOR;
			
			$perm01_Url = is_file( $dr.$bname.'_perm01.pdf' ) ? 'index.php?q=parcel/doc_down&img='.$bname.'_perm01' : '';
			$perm02_Url = is_file( $dr.$bname.'_perm02.pdf' ) ? 'index.php?q=parcel/doc_down&img='.$bname.'_perm02' : '';
			$perm03_Url = is_file( $dr.$bname.'_perm03.pdf' ) ? 'index.php?q=parcel/doc_down&img='.$bname.'_perm03' : '';
			
			$data->rows[$i]['id'] = $row['par_id'];
			$data->rows[$i]['cell'] = array(
					$row['par_id'],
					$this->gen_alert_status( $row ),
					$this->gen_edit_status( $row ),
					$row['par_build_id'],
				    $row['build_name'],
				    $row['build_address'],
					$row['height'],
					$row['poyt'],
					Tools::str_iso2local_date( $row['scsr'] ),
					Tools::str_iso2local_date( $row['los'] ),
					Tools::str_iso2local_date( $row['cwsr'] ),
					$row['loctype'],
					Tools::str_iso2local_date( $row['perm01_date'] ).$perm01_Url,
					Tools::str_iso2local_date( $row['perm02_date'] ).$perm02_Url,
					Tools::str_iso2local_date( $row['perm03_date'] ).$perm03_Url,
					Tools::str_iso2local_date( $row['rent'] ),
					Tools::str_iso2local_date( $row['decl01'] ),
					Tools::str_iso2local_date( $row['decl02'] ),
					$row['par_comment'],
		    );
		    $i++;
		}
    }
	catch (PDOException $e) {
		$data->userdata->errcode = 1;
		$data->userdata->errmess = ERR_M::DATABASE_ERROR;
	}
    catch ( Exception $e ) {
		$data->userdata->errcode = $e->getCode();
		$data->userdata->errmess = $e->getMessage();
	}
 
	return $data;
  }


  public function insert() {

    $par_build_id	= isset($_POST['par_build_id']) ? trim(strip_tags($_POST['par_build_id'])) : '';
    $build_name		= isset($_POST['build_name']) ? trim(strip_tags($_POST['build_name'])) : '';
    $par_comment	= isset($_POST['par_comment']) ? trim(strip_tags($_POST['par_comment'])) : '';
	
	$errcode = 0;
	$errmess = '';
    try
    {
// Открываем базу данных
		$db = App::me()->dbOpen();	

// Только зарегистрированные пользователи могут вносить данные
		if( !isset($_SESSION['user_id']) || $_SESSION['user_id'] == 0 )
			throw new Exception(ERR_M::TIMEOUT_ERROR, 999);
		$par_user_id = $_SESSION['user_id'];
		
//Есть ли разрешение на вставку записей
		$rwd = $_SESSION['priv']->parcel->rwd;
		if( ($rwd & PERM_BITS::WRITE_OWN) == 0 ) throw new Exception(ERR_M::DATA_OPER_DISABLED, 99);

// Все ли данные переданы
		$errdata = "";
		
// par_build_id  build_name
		if( $build_name == '' ) $errdata .= ($errdata?'<br>':'').'- Не указан шифр объекта.';
		elseif( !ctype_digit( $par_build_id ) ) 
			$errdata .= ($errdata?'<br>':'').'- Не указан идентификатор объекта.';
		else {
// Проверяем наличие обьекта в справочнике
			$recset = $db->query('SELECT build_id FROM builds WHERE build_id = '.$db->quote($par_build_id));                  
			$row = $recset->fetch(PDO::FETCH_ASSOC);
			if( !$row || $par_build_id != $row['build_id'] ) {
				$errdata .= ($errdata?'<br>':'').'- Неправильно указан идентификатор объекта.';
			}
			$recset->closeCursor();
		}
//				
// Если есть ошибки - можно уже закончить
//
		if( $errdata ) throw new Exception($errdata, 1);
		
// Может быть объект уже существует
		$sqlreq =	'SELECT build_name FROM parcel '.
					'INNER JOIN builds ON builds.build_id = parcel.par_build_id '.
					'WHERE par_build_id = '.$db->quote($par_build_id);
		$recset = $db->query( $sqlreq );
		
		$row = $recset->fetch(PDO::FETCH_ASSOC);
		if( $row ) {
			throw new Exception('Данные по объекту "'.$row['build_name'].'" уже присутствуют.', 1);
        }    
		$recset->closeCursor();

// Пишем данные
        $sqlreq =   'INSERT INTO parcel ( par_build_id, stage, stage_date, par_comment, par_user_id ) '.
                    'VALUES ('. $db->quote($par_build_id).", ".'1'.", ".$db->quote(date('Y-m-d H:i:s')).", ".
								$db->quote($par_comment).", ".$db->quote($par_user_id). ")";
		$db->exec($sqlreq);
    }
	catch (PDOException $e) {
		$errcode = 1;
		$errmess = ERR_M::DATABASE_ERROR;
	}
    catch ( Exception $e ) {
		$errcode = $e->getCode();
		$errmess = $e->getMessage();
	}

	return array('errcode'=>$errcode,'errmess'=>$errmess);
  }
  
/*  
  public function insert() {

    $par_build_id	= isset($_POST['par_build_id']) ? trim(strip_tags($_POST['par_build_id'])) : '';
    $build_name		= isset($_POST['build_name']) ? trim(strip_tags($_POST['build_name'])) : '';
    $height			= isset($_POST['height']) ? trim(strip_tags($_POST['height'])) : '';
    $poyt			= isset($_POST['poyt']) ? trim(strip_tags($_POST['poyt'])) : '';
    $scsr 			= isset($_POST['scsr']) ? trim(strip_tags($_POST['scsr'])) : '';
    $los			= isset($_POST['los']) ? trim(strip_tags($_POST['los'])) : '';
    $cwsr		 	= isset($_POST['cwsr']) ? trim(strip_tags($_POST['cwsr'])) : '';
    $start_cw	 	= isset($_POST['start_cw']) ? trim(strip_tags($_POST['start_cw'])) : '';
    $finish_cw		= isset($_POST['finish_cw']) ? trim(strip_tags($_POST['finish_cw'])) : '';
    $loctype		= isset($_POST['loctype']) ? trim(strip_tags($_POST['loctype'])) : '';
    $perm01_date	= isset($_POST['perm01_date']) ? trim(strip_tags($_POST['perm01_date'])) : '';
    $perm02_date	= isset($_POST['perm02_date']) ? trim(strip_tags($_POST['perm02_date'])) : '';
    $perm03_date	= isset($_POST['perm03_date']) ? trim(strip_tags($_POST['perm03_date'])) : '';
    $rent			= isset($_POST['rent']) ? trim(strip_tags($_POST['rent'])) : '';
    $decl01			= isset($_POST['decl01']) ? trim(strip_tags($_POST['decl01'])) : '';
    $decl02			= isset($_POST['decl02']) ? trim(strip_tags($_POST['decl02'])) : '';
    $par_comment	= isset($_POST['par_comment']) ? trim(strip_tags($_POST['par_comment'])) : '';
	
	$errcode = 0;
	$errmess = '';
    try
    {
// Открываем базу данных
		$db = App::me()->dbOpen();	

// Только зарегистрированные пользователи могут вносить данные
		if( !isset($_SESSION['user_id']) || $_SESSION['user_id'] == 0 )
			throw new Exception(ERR_M::TIMEOUT_ERROR, 999);
		$par_user_id = $_SESSION['user_id'];
		
// Все ли данные переданы
		$errdata = "";
		
// par_build_id  build_name
		if( $build_name == '' ) $errdata .= ($errdata?'<br>':'').'- Не указан шифр объекта.';
		elseif( !ctype_digit( $par_build_id ) ) 
			$errdata .= ($errdata?'<br>':'').'- Не указан идентификатор объекта.';
		else {
// Проверяем наличие обьекта в справочнике
			$recset = $db->query('SELECT build_id FROM builds WHERE build_id = '.$db->quote($par_build_id));                  
			$row = $recset->fetch(PDO::FETCH_ASSOC);
			if( !$row ) {
				$errdata .= ($errdata?'<br>':'').'- Неправильно указан идентификатор объекта.';
			}
			$recset->closeCursor();
		}

// height			
		if( $height == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана высота мачты.";
		else {
			if( !ctype_digit( $height ) )
				$errdata .= ($errdata?'<br>':'')."- Неправильно указана высота мачты.";
		}
			
// poyt
		if( $poyt == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана дата PO YT.";
		elseif( ( $poyt = Tools::check_date($poyt) ) === false )
			$errdata .= ($errdata?'<br>':'')."- Дата PO YT указана неправильно.";

// scsr
		if( $scsr == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана дата SCSR.";
		elseif( ( $scsr = Tools::check_date($scsr) ) === false )
			$errdata .= ($errdata?'<br>':'')."- Дата SCSR указана неправильно.";

// los
		if( $los == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана дата LOS.";
		elseif( ( $los = Tools::check_date($los) ) === false )
			$errdata .= ($errdata?'<br>':'')."- Дата LOS указана неправильно.";

// cwsr
		if( $cwsr == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана дата CWSR.";
		elseif( ( $cwsr = Tools::check_date($cwsr) ) === false )
			$errdata .= ($errdata?'<br>':'')."- Дата CWSR указана неправильно.";

// start_cw
		if( $start_cw == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана дата 'Старт CW'.";
		elseif( ( $start_cw = Tools::check_date($start_cw) ) === false )
			$errdata .= ($errdata?'<br>':'')."- Дата 'Старт CW' указана неправильно.";

// finish_cw
		if( $finish_cw == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана дата 'Финиш CW'.";
		elseif( ( $finish_cw = Tools::check_date($finish_cw) ) === false )
			$errdata .= ($errdata?'<br>':'')."- Дата 'Финиш CW' указана неправильно.";

// loctype			
		if( $loctype == '' ) $errdata .= ($errdata?'<br>':'')."- Не указан тип расположения.";
		else {
			if( !ctype_digit( $loctype ) || $loctype < 0 || $loctype > 2 )
				$errdata .= ($errdata?'<br>':'')."- Неправильно указан тип расположения.";
		}

// perm01_date		
		if( $perm01_date == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана 'Дата решения 1'.";
		elseif( ( $perm01_date = Tools::check_date($perm01_date) ) === false )
			$errdata .= ($errdata?'<br>':'')."- 'Дата решения 1' указана неправильно.";

// perm02_date		
		if( $perm02_date == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана 'Дата решения 2'.";
		elseif( ( $perm02_date = Tools::check_date($perm02_date) ) === false )
			$errdata .= ($errdata?'<br>':'')."- 'Дата решения 2' указана неправильно.";

// perm03_date		
		if( $perm03_date == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана 'Дата решения 3'.";
		elseif( ( $perm03_date = Tools::check_date($perm03_date) ) === false )
			$errdata .= ($errdata?'<br>':'')."- 'Дата решения 3' указана неправильно.";

// rent		
		if( $rent == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана 'Дата договора аренды'.";
		elseif( ( $rent = Tools::check_date($rent) ) === false )
			$errdata .= ($errdata?'<br>':'')."- 'Дата договора аренды' указана неправильно.";

// decl01		
		if( $decl01 == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана дата 'Декларация 1'.";
		elseif( ( $decl01 = Tools::check_date($decl01) ) === false )
			$errdata .= ($errdata?'<br>':'')."- Дата 'Декларация 1' указана неправильно.";

// decl02		
		if( $decl02 == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана дата 'Декларация 2'.";
		elseif( ( $decl02 = Tools::check_date($decl02) ) === false )
			$errdata .= ($errdata?'<br>':'')."- Дата 'Декларация 2' указана неправильно.";

//				
// Если есть ошибки - можно уже закончить
//
		if( $errdata ) throw new Exception($errdata, 1);
		
// Может быть платеж уже существует
		$sqlreq =	'SELECT build_name FROM parcel '.
					'INNER JOIN builds ON builds.build_id = parcel.par_build_id '.
					'WHERE par_build_id = '.$db->quote($par_build_id);
		$recset = $db->query( $sqlreq );
		
		$row = $recset->fetch(PDO::FETCH_ASSOC);
		if( $row ) {
			throw new Exception('Данные по объекту "'.$row['build_name'].'" уже присутствуют.', 1);
        }    
		$recset->closeCursor();

// Пишем данные
        $sqlreq =   'INSERT INTO parcel ( par_build_id, height, poyt, scsr, los, cwsr, start_cw, finish_cw, '.
						'loctype, perm01_date, perm02_date, perm03_date, '.
						'rent, decl01, decl02, stage, stage_date, par_comment, par_user_id ) '.
                    'VALUES ('. $db->quote($par_build_id).", ".$db->quote($height).", ".$db->quote($poyt).", ".$db->quote($scsr).", ".
                                $db->quote($los).", ".$db->quote($cwsr).", ".$db->quote($start_cw).", ".$db->quote($finish_cw).", ".
                                $db->quote($loctype).", ".$db->quote($perm01_date).", ".
								$db->quote($perm02_date).", ".$db->quote($perm03_date).", ".
								$db->quote($rent).", ".$db->quote($decl01).", ".$db->quote($decl02).", ".
								'0'.", ".$db->quote(date('Y-m-d')).", ".$db->quote($par_comment).", ".$db->quote($par_user_id). ")";
		$db->exec($sqlreq);
    }
	catch (PDOException $e) {
		$errcode = 1;
		$errmess = ERR_M::DATABASE_ERROR;
	}
    catch ( Exception $e ) {
		$errcode = $e->getCode();
		$errmess = $e->getMessage();
	}

	return array('errcode'=>$errcode,'errmess'=>$errmess);
  }
*/


  private function stage1_update( $db, $r ) {

	$errdata = '';
	
    $par_id			= isset($_POST['id']) ? trim(strip_tags($_POST['id'])) : '';
    $par_build_id	= isset($_POST['par_build_id']) ? trim(strip_tags($_POST['par_build_id'])) : '';
    $build_name		= isset($_POST['build_name']) ? trim(strip_tags($_POST['build_name'])) : '';
    $height			= isset($_POST['height']) ? trim(strip_tags($_POST['height'])) : '';
    $poyt			= isset($_POST['poyt']) ? trim(strip_tags($_POST['poyt'])) : '';
    $scsr 			= isset($_POST['scsr']) ? trim(strip_tags($_POST['scsr'])) : '';
    $los			= isset($_POST['los']) ? trim(strip_tags($_POST['los'])) : '';
    $cwsr		 	= isset($_POST['cwsr']) ? trim(strip_tags($_POST['cwsr'])) : '';
    $loctype		= isset($_POST['loctype']) ? trim(strip_tags($_POST['loctype'])) : '';
    $par_comment 	= isset($_POST['par_comment']) ? trim(strip_tags($_POST['par_comment'])) : '';

// par_build_id  build_name
	if( $build_name == '' ) $errdata .= ($errdata?'<br>':'').'- Не указан шифр объекта.';
	elseif( !ctype_digit( $par_build_id ) ) 
		$errdata .= ($errdata?'<br>':'').'- Не указан идентификатор объекта.';
	else {
// Проверяем наличие обьекта в справочнике
		$recset = $db->query('SELECT build_id FROM builds WHERE build_id = '.$db->quote($par_build_id));                  
		$row = $recset->fetch(PDO::FETCH_ASSOC);
		if( !$row ) {
			$errdata .= ($errdata?'<br>':'').'- Неправильно указан идентификатор объекта.';
		}
		$recset->closeCursor();
	}

// height			
	if( $height != '' && $height != '0' && !ctype_digit( $height ) )
		$errdata .= ($errdata?'<br>':'')."- Неправильно указана высота мачты.";
			
// scsr
	if( $scsr != '' ) {
		if( ( $scsr = Tools::check_date($scsr) ) === false )
			$errdata .= ($errdata?'<br>':'')."- Дата SCSR указана неправильно.";
		elseif( time() < strtotime( $scsr ) )
			$errdata .= ($errdata?'<br>':'')."- Дата SCSR не может быть больше текущей даты";
	}
			
// los
	if( $los != '' ) { 
		if( ( $los = Tools::check_date($los) ) === false )
			$errdata .= ($errdata?'<br>':'')."- Дата LOS указана неправильно.";
		elseif( time() < strtotime( $los ) )
			$errdata .= ($errdata?'<br>':'')."- Дата LOS не может быть больше текущей даты";
	}
	
// cwsr
	if( $cwsr != '' ) {
		if( ( $cwsr = Tools::check_date($cwsr) ) === false )
			$errdata .= ($errdata?'<br>':'')."- Дата CWSR указана неправильно.";
		elseif( time() < strtotime( $cwsr ) )
			$errdata .= ($errdata?'<br>':'')."- Дата CWSR не может быть больше текущей даты";
	}
	
// loctype			
	if( $loctype != '' && $loctype != '0' ) {
		if( !ctype_digit( $loctype ) || $loctype < 1 || $loctype > 2 )
			$errdata .= ($errdata?'<br>':'')."- Неправильно указан тип расположения.";
	}
	
//				
// Если есть ошибки - можно уже закончить
//		
	if( $errdata ) throw new Exception($errdata, 1);
		
// Может быть объект с указаным именем уже существует
	$sqlreq =	'SELECT build_name FROM parcel '.
				'INNER JOIN builds ON builds.build_id = parcel.par_build_id '.
				'WHERE par_build_id = '.$db->quote($par_build_id).' AND '.
						'par_id != '.$db->quote($par_id);
							
	$recset = $db->query( $sqlreq );
		
	$row = $recset->fetch(PDO::FETCH_ASSOC);
	if( $row ) {
		throw new Exception('Данные по объекту "'.$row['build_name'].'" уже присутствуют.', 1);
    }    
	$recset->closeCursor();

// Готовим данные
	$val = array();

// Обязательные данные для закрытия этапа
	if( $height != '' && $height != '0' ) $val[] = 'height = '.$db->quote($height);
	if( $scsr != '' ) $val[] = 'scsr = '.	$db->quote($scsr);
	if( $los != '' )  $val[] = 'los = '.	$db->quote($los);
	if( $cwsr != '' ) $val[] = 'cwsr = '.	$db->quote($cwsr);
	if( $loctype != '' && $loctype != '0' ) $val[] = 'loctype = '.$db->quote($loctype);
	
	if( count( $val ) == 5 ) {
		$val[] = "stage = '2'";
		$val[] = "stage_date = ".$db->quote(date('Y-m-d H:i:s')); 
	}
// Необязательные данные этапа
	$val[] = 'par_comment = '.	$db->quote($par_comment);
	$val[] = 'poyt = '.$db->quote($poyt);

// Данные предидущего этапа. Периода "дребезга"	
	$iv = Tools::how_many('sec', $r['stage_date']) < $this->bounce_time; 
	if( $iv ) $val[] = 'par_build_id = '. $db->quote($par_build_id);

    $sqlreq =   'UPDATE parcel SET ' . implode( ", ", $val ) . ' WHERE par_id = '.$r['par_id'];
												
	$db->exec($sqlreq);  
  }


  private function stage2_update( $db, $r ) {
  
	$errdata = '';
	
    $par_id			= isset($_POST['id']) ? trim(strip_tags($_POST['id'])) : '';
    $height			= isset($_POST['height']) ? trim(strip_tags($_POST['height'])) : '';
    $poyt			= isset($_POST['poyt']) ? trim(strip_tags($_POST['poyt'])) : '';
    $scsr 			= isset($_POST['scsr']) ? trim(strip_tags($_POST['scsr'])) : '';
    $los			= isset($_POST['los']) ? trim(strip_tags($_POST['los'])) : '';
    $cwsr		 	= isset($_POST['cwsr']) ? trim(strip_tags($_POST['cwsr'])) : '';
    $loctype		= isset($_POST['loctype']) ? trim(strip_tags($_POST['loctype'])) : '';
    $perm01_date	= isset($_POST['perm01_date']) ? trim(strip_tags($_POST['perm01_date'])) : '';
    $par_comment 	= isset($_POST['par_comment']) ? trim(strip_tags($_POST['par_comment'])) : '';
	
	$stdt = date( 'd.m.Y', strtotime($r['stage_date']) );
	
// height			
	if( $height == '' || $height == '0' ) $errdata .= ($errdata?'<br>':'')."- Не указана высота мачты.";
	elseif( !ctype_digit( $height ) ) {
			$errdata .= ($errdata?'<br>':'')."- Неправильно указана высота мачты.";
	}
			
// scsr
	if( $scsr == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана дата SCSR.";
	elseif( ( $scsr = Tools::check_date($scsr) ) === false )
		$errdata .= ($errdata?'<br>':'')."- Дата SCSR указана неправильно.";
	elseif( strtotime( $r['stage_date'] ) < strtotime( $scsr ) )
		$errdata .= ($errdata?'<br>':'')."- Дата SCSR не может быть больше ".$stdt;

// los
	if( $los == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана дата LOS.";
	elseif( ( $los = Tools::check_date($los) ) === false )
		$errdata .= ($errdata?'<br>':'')."- Дата LOS указана неправильно.";
	elseif( strtotime( $r['stage_date'] ) < strtotime( $los ) )
		$errdata .= ($errdata?'<br>':'')."- Дата LOS не может быть больше ".$stdt;

// cwsr
	if( $cwsr == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана дата CWSR.";
	elseif( ( $cwsr = Tools::check_date($cwsr) ) === false )
		$errdata .= ($errdata?'<br>':'')."- Дата CWSR указана неправильно.";
	elseif( strtotime( $r['stage_date'] ) < strtotime( $cwsr ) )
		$errdata .= ($errdata?'<br>':'')."- Дата CWSR не может быть больше ".$stdt;

// loctype			
	if( $loctype == '' || $loctype == '0' ) $errdata .= ($errdata?'<br>':'')."- Не указан тип расположения.";
	elseif( !ctype_digit( $loctype ) || $loctype < 1 || $loctype > 2 )
		$errdata .= ($errdata?'<br>':'')."- Неправильно указан тип расположения.";
	
 // perm01_date		
	if( $perm01_date != '' ) {
		if( ( $perm01_date = Tools::check_date($perm01_date) ) === false )
			$errdata .= ($errdata?'<br>':'')."- 'Дата решения 1' указана неправильно.";
		elseif( time() < strtotime( $perm01_date ) )
			$errdata .= ($errdata?'<br>':'')."- Дата 'Решение 1' не может быть больше текущей даты";
	}

//				
// Если есть ошибки - можно уже закончить
//		
	if( $errdata ) throw new Exception($errdata, 1);
		
// Готовим данные
	$val = array();

// Обязательные данные для закрытия этапа
	if( $perm01_date != '' ) $val[] = 'perm01_date = '.	$db->quote($perm01_date);
	
	if( count( $val ) == 1 ) {
		$val[] = "stage = ".$db->quote(($loctype == 1) ? 4 : 3);
		$val[] = "stage_date = ".$db->quote(date('Y-m-d H:i:s')); 
	}
	
// Необязательные данные этапа
	$val[] = 'par_comment = '.	$db->quote($par_comment);

// Данные предидущего этапа. Периода "дребезга"	
	$iv = Tools::how_many('sec', $r['stage_date']) < $this->bounce_time; 
	if( $iv ) {
		$val[] = 'height = '.$db->quote($height);
		$val[] = 'poyt = '.	$db->quote($poyt);
		$val[] = 'scsr = '.	$db->quote($scsr);
		$val[] = 'los = '.	$db->quote($los);
		$val[] = 'cwsr = '.	$db->quote($cwsr);
		$val[] = 'loctype = '.$db->quote($loctype);
	}

// Пишем данные
    $sqlreq =   'UPDATE parcel SET ' . implode( ", ", $val ) . ' WHERE par_id = '.$r['par_id'];												
	$db->exec($sqlreq);   
  }

  
  private function stage3_update( $db, $r ) {
  
	$errdata = '';
	
    $par_id			= isset($_POST['id']) ? trim(strip_tags($_POST['id'])) : '';
    $perm01_date	= isset($_POST['perm01_date']) ? trim(strip_tags($_POST['perm01_date'])) : '';
    $perm02_date	= isset($_POST['perm02_date']) ? trim(strip_tags($_POST['perm02_date'])) : '';
    $par_comment 	= isset($_POST['par_comment']) ? trim(strip_tags($_POST['par_comment'])) : '';
	
	$stdt = date( 'd.m.Y', strtotime($r['stage_date']) );

// Данные предидущего этапа	
// perm01_date
	if( $perm01_date == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана дата 'Решение 1'.";
	elseif( ( $perm01_date = Tools::check_date($perm01_date) ) === false )
		$errdata .= ($errdata?'<br>':'')."- Дата 'Решение 1' указана неправильно.";
	elseif( strtotime( $r['stage_date'] ) < strtotime( $perm01_date ) )
		$errdata .= ($errdata?'<br>':'')."- Дата 'Решение 1' не может быть больше ".$stdt;

 // perm02_date		
	if( $perm02_date != '' ) {
		if( ( $perm02_date = Tools::check_date($perm02_date) ) === false )
			$errdata .= ($errdata?'<br>':'')."- Дата 'Решение 2' указана неправильно.";
		elseif( time() < strtotime( $perm02_date ) )
			$errdata .= ($errdata?'<br>':'')."- Дата 'Решение 2' не может быть больше текущей даты";
	}

//				
// Если есть ошибки - можно уже закончить
//		
	if( $errdata ) throw new Exception($errdata, 1);
		
// Готовим данные
	$val = array();

// Обязательные данные для закрытия этапа
	if( $perm02_date != '' ) $val[] = 'perm02_date = '.	$db->quote($perm02_date);
	
	if( count( $val ) == 1 ) {
		$val[] = "stage = '4'";
		$val[] = "stage_date = ".$db->quote(date('Y-m-d H:i:s')); 
	}
	
// Необязательные данные этапа
	$val[] = 'par_comment = '.	$db->quote($par_comment);

// Данные предидущего этапа. Периода "дребезга"	
	$iv = Tools::how_many('sec', $r['stage_date']) < $this->bounce_time; 
	if( $iv ) {
		$val[] = 'perm01_date = '.$db->quote($perm01_date);
	}

// Пишем данные
    $sqlreq =   'UPDATE parcel SET ' . implode( ", ", $val ) . ' WHERE par_id = '.$r['par_id'];												
	$db->exec($sqlreq);   
  }

  
  private function stage4_update( $db, $r ) {
  
	$errdata = '';
	$skip = ( $r['loctype'] == 1 );
	
    $par_id			= isset($_POST['id']) ? trim(strip_tags($_POST['id'])) : '';
	if( $skip )	$perm01_date	= isset($_POST['perm01_date']) ? trim(strip_tags($_POST['perm01_date'])) : '';
	else		$perm02_date	= isset($_POST['perm02_date']) ? trim(strip_tags($_POST['perm02_date'])) : '';
    $perm03_date	= isset($_POST['perm03_date']) ? trim(strip_tags($_POST['perm03_date'])) : '';
    $par_comment 	= isset($_POST['par_comment']) ? trim(strip_tags($_POST['par_comment'])) : '';
	
	$stdt = date( 'd.m.Y', strtotime($r['stage_date']) );

// Данные предидущего этапа	
// perm01_date || perm02_date

	if( $skip ) {
		if( $perm01_date == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана дата 'Решение 1'.";
		elseif( ( $perm01_date= Tools::check_date($perm01_date) ) === false )
			$errdata .= ($errdata?'<br>':'')."- Дата 'Решение 1' указана неправильно.";
		elseif( strtotime( $r['stage_date'] ) < strtotime( $perm01_date ) )
			$errdata .= ($errdata?'<br>':'')."- Дата 'Решение 1' не может быть больше ".$stdt;	
	}
	else {
		if( $perm02_date == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана дата 'Решение 2'.";
		elseif( ( $perm02_date = Tools::check_date($perm02_date) ) === false )
			$errdata .= ($errdata?'<br>':'')."- Дата 'Решение 2' указана неправильно.";
		elseif( strtotime( $r['stage_date'] ) < strtotime( $perm02_date ) )
			$errdata .= ($errdata?'<br>':'')."- Дата 'Решение 2' не может быть больше ".$stdt;
	}
	
 // perm03_date		
	if( $perm03_date != '' ) {
		if( ( $perm03_date = Tools::check_date($perm03_date) ) === false )
			$errdata .= ($errdata?'<br>':'')."- Дата 'Решение 3' указана неправильно.";
		elseif( time() < strtotime( $perm03_date ) )
			$errdata .= ($errdata?'<br>':'')."- Дата 'Решение 3' не может быть больше текущей даты";
	}

//				
// Если есть ошибки - можно уже закончить
//		
	if( $errdata ) throw new Exception($errdata, 1);
		
// Готовим данные
	$val = array();

// Обязательные данные для закрытия этапа
	if( $perm03_date != '' ) $val[] = 'perm03_date = '.	$db->quote($perm03_date);
	
	if( count( $val ) == 1 ) {
		$val[] = "stage = '5'";
		$val[] = "stage_date = ".$db->quote(date('Y-m-d H:i:s')); 
	}
	
// Необязательные данные этапа
	$val[] = 'par_comment = '.	$db->quote($par_comment);

// Данные предидущего этапа. Периода "дребезга"	
	$iv = Tools::how_many('sec', $r['stage_date']) < $this->bounce_time; 
	if( $iv ) {
		if( $skip )	$val[] = 'perm01_date = '.$db->quote($perm01_date);
		else	$val[] = 'perm02_date = '.$db->quote($perm02_date);
	}

// Пишем данные
    $sqlreq =   'UPDATE parcel SET ' . implode( ", ", $val ) . ' WHERE par_id = '.$r['par_id'];												
	$db->exec($sqlreq);   
  }

  
  private function stage5_update( $db, $r ) {
  
	$errdata = '';
	
    $par_id			= isset($_POST['id']) ? trim(strip_tags($_POST['id'])) : '';
    $perm03_date	= isset($_POST['perm03_date']) ? trim(strip_tags($_POST['perm03_date'])) : '';
    $rent	= isset($_POST['rent']) ? trim(strip_tags($_POST['rent'])) : '';
    $par_comment 	= isset($_POST['par_comment']) ? trim(strip_tags($_POST['par_comment'])) : '';
	
	$stdt = date( 'd.m.Y', strtotime($r['stage_date']) );

// Данные предидущего этапа	
// perm03_date
	if( $perm03_date == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана дата 'Решение 3'.";
	elseif( ( $perm03_date = Tools::check_date($perm03_date) ) === false )
		$errdata .= ($errdata?'<br>':'')."- Дата 'Решение 3' указана неправильно.";
	elseif( strtotime( $r['stage_date'] ) < strtotime( $perm03_date ) )
		$errdata .= ($errdata?'<br>':'')."- Дата 'Решение 3' не может быть больше ".$stdt;

 // rent	
	if( $rent != '' ) {
		if( ( $rent = Tools::check_date($rent) ) === false )
			$errdata .= ($errdata?'<br>':'')."- Дата 'Оренда' указана неправильно.";
		elseif( time() < strtotime( $rent ) )
			$errdata .= ($errdata?'<br>':'')."- Дата 'Оренда' не может быть больше текущей даты";
	}

//				
// Если есть ошибки - можно уже закончить
//		
	if( $errdata ) throw new Exception($errdata, 1);
		
// Готовим данные
	$val = array();

// Обязательные данные для закрытия этапа
	if( $rent != '' ) $val[] = 'rent = '.	$db->quote($rent);
	
	if( count( $val ) == 1 ) {
		$val[] = "stage = '6'";
		$val[] = "stage_date = ".$db->quote(date('Y-m-d H:i:s')); 
	}
	
// Необязательные данные этапа
	$val[] = 'par_comment = '.	$db->quote($par_comment);

// Данные предидущего этапа. Периода "дребезга"	
	$iv = Tools::how_many('sec', $r['stage_date']) < $this->bounce_time; 
	if( $iv ) {
		$val[] = 'perm03_date = '.$db->quote($perm03_date);
	}

// Пишем данные
    $sqlreq =   'UPDATE parcel SET ' . implode( ", ", $val ) . ' WHERE par_id = '.$r['par_id'];												
	$db->exec($sqlreq);   
  }

  
  private function stage6_update( $db, $r ) {
  
	$errdata = '';
	
    $par_id		= isset($_POST['id']) ? trim(strip_tags($_POST['id'])) : '';
    $rent		= isset($_POST['rent']) ? trim(strip_tags($_POST['rent'])) : '';
    $decl01		= isset($_POST['decl01']) ? trim(strip_tags($_POST['decl01'])) : '';
    $par_comment = isset($_POST['par_comment']) ? trim(strip_tags($_POST['par_comment'])) : '';
	
	$stdt = date( 'd.m.Y', strtotime($r['stage_date']) );

// Данные предидущего этапа	
// rent
	if( $rent == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана дата 'Оренда'.";
	elseif( ( $rent = Tools::check_date($rent) ) === false )
		$errdata .= ($errdata?'<br>':'')."- Дата 'Оренда' указана неправильно.";
	elseif( strtotime( $r['stage_date'] ) < strtotime( $rent ) )
		$errdata .= ($errdata?'<br>':'')."- Дата 'Оренда' не может быть больше ".$stdt;

 // decl01	
	if( $decl01 != '' ) {
		if( ( $decl01 = Tools::check_date($decl01) ) === false )
			$errdata .= ($errdata?'<br>':'')."- Дата 'Декларация 1' указана неправильно.";
		elseif( time() < strtotime( $decl01 ) )
			$errdata .= ($errdata?'<br>':'')."- Дата 'Декларация 1' не может быть больше текущей даты";
	}

//				
// Если есть ошибки - можно уже закончить
//		
	if( $errdata ) throw new Exception($errdata, 1);
		
// Готовим данные
	$val = array();

// Обязательные данные для закрытия этапа
	if( $decl01 != '' ) $val[] = 'decl01 = '.	$db->quote($decl01);
	
	if( count( $val ) == 1 ) {
		$val[] = "stage = '7'";
		$val[] = "stage_date = ".$db->quote(date('Y-m-d H:i:s')); 
	}
	
// Необязательные данные этапа
	$val[] = 'par_comment = '.	$db->quote($par_comment);

// Данные предидущего этапа. Периода "дребезга"	
	$iv = Tools::how_many('sec', $r['stage_date']) < $this->bounce_time; 
	if( $iv ) {
		$val[] = 'rent = '.$db->quote($rent);
	}

// Пишем данные
    $sqlreq =   'UPDATE parcel SET ' . implode( ", ", $val ) . ' WHERE par_id = '.$r['par_id'];												
	$db->exec($sqlreq);   
  }

  
  private function stage7_update( $db, $r ) {
  
	$errdata = '';
	
    $par_id			= isset($_POST['id']) ? trim(strip_tags($_POST['id'])) : '';
    $decl01	= isset($_POST['decl01']) ? trim(strip_tags($_POST['decl01'])) : '';
    $decl02	= isset($_POST['decl02']) ? trim(strip_tags($_POST['decl02'])) : '';
    $par_comment = isset($_POST['par_comment']) ? trim(strip_tags($_POST['par_comment'])) : '';
	
	$stdt = date( 'd.m.Y', strtotime($r['stage_date']) );

// Данные предидущего этапа	
// decl01
	if( $decl01 == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана дата 'Декларация 1'.";
	elseif( ( $decl01 = Tools::check_date($decl01) ) === false )
		$errdata .= ($errdata?'<br>':'')."- Дата 'Декларация 1' указана неправильно.";
	elseif( strtotime( $r['stage_date'] ) < strtotime( $decl01 ) )
		$errdata .= ($errdata?'<br>':'')."- Дата 'Декларация 1' не может быть больше ".$stdt;

 // decl02	
	if( $decl02 != '' ) {
		if( ( $decl02 = Tools::check_date($decl02) ) === false )
			$errdata .= ($errdata?'<br>':'')."- Дата 'Декларация 2' указана неправильно.";
		elseif( time() < strtotime( $decl02 ) )
			$errdata .= ($errdata?'<br>':'')."- Дата 'Декларация 2' не может быть больше текущей даты";
	}

//				
// Если есть ошибки - можно уже закончить
//		
	if( $errdata ) throw new Exception($errdata, 1);
		
// Готовим данные
	$val = array();

// Обязательные данные для закрытия этапа
	if( $decl02 != '' ) $val[] = 'decl02 = '.$db->quote($decl02);
	
	if( count( $val ) == 1 ) {
		$val[] = "stage = '8'";
		$val[] = "stage_date = ".$db->quote(date('Y-m-d H:i:s')); 
	}
	
// Необязательные данные этапа
	$val[] = 'par_comment = '.	$db->quote($par_comment);

// Данные предидущего этапа. Периода "дребезга"	
	$iv = Tools::how_many('sec', $r['stage_date']) < $this->bounce_time; 
	if( $iv ) {
		$val[] = 'decl01 = '.$db->quote($decl01);
	}

// Пишем данные
    $sqlreq =   'UPDATE parcel SET ' . implode( ", ", $val ) . ' WHERE par_id = '.$r['par_id'];												
	$db->exec($sqlreq);   
  }

  
  private function stage8_update( $db, $r ) {
  
	$errdata = '';
	
    $par_id			= isset($_POST['id']) ? trim(strip_tags($_POST['id'])) : '';
    $decl02	= isset($_POST['decl02']) ? trim(strip_tags($_POST['decl02'])) : '';
    $par_comment = isset($_POST['par_comment']) ? trim(strip_tags($_POST['par_comment'])) : '';
	
	$stdt = date( 'd.m.Y', strtotime($r['stage_date']) );

// Данные предидущего этапа	
// decl02
	if( $decl02 == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана дата 'Декларация 2'.";
	elseif( ( $decl02 = Tools::check_date($decl02) ) === false )
		$errdata .= ($errdata?'<br>':'')."- Дата 'Декларация 2' указана неправильно.";
	elseif( strtotime( $r['stage_date'] ) < strtotime( $decl02 ) )
		$errdata .= ($errdata?'<br>':'')."- Дата 'Декларация 2' не может быть больше ".$stdt;

//				
// Если есть ошибки - можно уже закончить
//		
	if( $errdata ) throw new Exception($errdata, 1);
		
// Готовим данные
	$val = array();

// Необязательные данные этапа
	$val[] = 'par_comment = '.	$db->quote($par_comment);
		
// Данные предидущего этапа. Периода "дребезга"	
	$iv = Tools::how_many('sec', $r['stage_date']) < $this->bounce_time; 
	if( $iv ) {
		$val[] = 'decl02 = '.$db->quote($decl02);
	}

// Пишем данные
    $sqlreq =   'UPDATE parcel SET ' . implode( ", ", $val ) . ' WHERE par_id = '.$r['par_id'];												
	$db->exec($sqlreq);   
  }

  
  public function update() {
	
    $par_id	= isset($_POST['id']) ? trim(strip_tags($_POST['id'])) : '';

	$errcode = 0;
	$errmess = '';
    try
    {
// Открываем базу данных
		$db = App::me()->dbOpen();	

// Только зарегистрированные пользователи могут вносить данные
		if( !isset($_SESSION['user_id']) || $_SESSION['user_id'] == 0 )
			throw new Exception(ERR_M::TIMEOUT_ERROR, 999);
		$par_user_id = $_SESSION['user_id'];

// Есть ли разрешение на изменение чьей либо записи
		$rwd = $_SESSION['priv']->parcel->rwd;
		if( ($rwd & PERM_BITS::WRITE_ANY) == 0 ) throw new Exception(ERR_M::DATA_OPER_DISABLED, 99);
		
// Все ли данные переданы
		$errdata = "";
		
// par_id
		if( $par_id == '' ) {
			$errdata = "Не указан идентификатор записи.";
		}
		else {
// Получим инфу о текущем этапе
			$recset = $db->query( 'SELECT * FROM parcel WHERE par_id = '.$db->quote($par_id) );		
			$row = $recset->fetch(PDO::FETCH_ASSOC);
			if( !$row ) {
				$errdata = 'Странно!?. Куда-то ищезла ред.запись. Обратитесь к админу системы';
			}
			else
				$r = $row;
			
			$recset->closeCursor();
		}
//				
// Если есть ошибки - можно уже закончить
//		
		if( $errdata ) throw new Exception($errdata, 1);
		
// Есть ли разрешение на апдейт этой записи
		if( $rwd & PERM_BITS::WRITE_OTH ) $where = '1 = 1';
		elseif( $rwd & PERM_BITS::WRITE_GRP ) 
			$where = 'par_user_id IN (SELECT user_id FROM users WHERE cat_id = '.$_SESSION['cat_id'].')';
		elseif( $rwd & PERM_BITS::WRITE_OWN ) $where = 'par_user_id = '.$_SESSION['user_id'];
		else $where = '1 = 0';
		$where .= ' AND par_id = '.$db->quote($par_id);
		
		$sqlreq = 'SELECT COUNT(*) AS count FROM parcel WHERE '.$where.' LIMIT 1';
		$recset = $db->query( $sqlreq );		
		$row = $recset->fetch(PDO::FETCH_ASSOC);
		if( !$row['count'] ) {
			throw new Exception(ERR_M::DATA_OWNER_DISABLED, 99);
        }    
		$recset->closeCursor();

// Выполним нужный этап		
		switch( $r['stage'] ) {
			case 1: $this->stage1_update( $db, $r ); break;
			case 2: $this->stage2_update( $db, $r ); break;
			case 3: $this->stage3_update( $db, $r ); break;
			case 4: $this->stage4_update( $db, $r ); break;
			case 5: $this->stage5_update( $db, $r ); break;
			case 6: $this->stage6_update( $db, $r ); break;
			case 7: $this->stage7_update( $db, $r ); break;
			case 8: $this->stage8_update( $db, $r ); break;
			default:
				throw new Exception("Неизвестный этап изменения данных", 1);
		}		
    }
	catch (PDOException $e) {
		$errcode = 1;
//		$errmess = ERR_M::DATABASE_ERROR;
		$errmess = $e->getMessage();
	}
    catch ( Exception $e ) {
		$errcode = $e->getCode();
		$errmess = $e->getMessage();
	}

	return array('errcode'=>$errcode,'errmess'=>$errmess);
  }

/*  
  public function update() {
	
    $par_id			= isset($_POST['id']) ? trim(strip_tags($_POST['id'])) : '';
    $par_build_id	= isset($_POST['par_build_id']) ? trim(strip_tags($_POST['par_build_id'])) : '';
    $build_name		= isset($_POST['build_name']) ? trim(strip_tags($_POST['build_name'])) : '';
    $height			= isset($_POST['height']) ? trim(strip_tags($_POST['height'])) : '';
    $poyt			= isset($_POST['poyt']) ? trim(strip_tags($_POST['poyt'])) : '';
    $scsr 			= isset($_POST['scsr']) ? trim(strip_tags($_POST['scsr'])) : '';
    $los			= isset($_POST['los']) ? trim(strip_tags($_POST['los'])) : '';
    $cwsr		 	= isset($_POST['cwsr']) ? trim(strip_tags($_POST['cwsr'])) : '';
    $start_cw	 	= isset($_POST['start_cw']) ? trim(strip_tags($_POST['start_cw'])) : '';
    $finish_cw		= isset($_POST['finish_cw']) ? trim(strip_tags($_POST['finish_cw'])) : '';
    $loctype		= isset($_POST['loctype']) ? trim(strip_tags($_POST['loctype'])) : '';
    $perm01_date	= isset($_POST['perm01_date']) ? trim(strip_tags($_POST['perm01_date'])) : '';
    $perm02_date	= isset($_POST['perm02_date']) ? trim(strip_tags($_POST['perm02_date'])) : '';
    $perm03_date	= isset($_POST['perm03_date']) ? trim(strip_tags($_POST['perm03_date'])) : '';
    $rent			= isset($_POST['rent']) ? trim(strip_tags($_POST['rent'])) : '';
    $decl01			= isset($_POST['decl01']) ? trim(strip_tags($_POST['decl01'])) : '';
    $decl02			= isset($_POST['decl02']) ? trim(strip_tags($_POST['decl02'])) : '';
    $par_comment	= isset($_POST['par_comment']) ? trim(strip_tags($_POST['par_comment'])) : '';

	$errcode = 0;
	$errmess = '';
    try
    {
// Открываем базу данных
		$db = App::me()->dbOpen();	

// Только зарегистрированные пользователи могут вносить данные
		if( !isset($_SESSION['user_id']) || $_SESSION['user_id'] == 0 )
			throw new Exception(ERR_M::TIMEOUT_ERROR, 999);
		$par_user_id = $_SESSION['user_id'];

// Все ли данные переданы
		$errdata = "";
		
// par_id
		if( $par_id == '' ) {
			$errdata = "Не указан идентификатор записи.";
		}
		else {
// Получим инфу о текущем этапе
			$recset = $db->query( 'SELECT stage, stage_date FROM parcel WHERE par_id = '.$db->quote($par_id) );		
			$row = $recset->fetch(PDO::FETCH_ASSOC);
			if( !$row ) {
				$errdata = 'Странно!?. Куда-то ищезла ред.запись. Обратитесь к админу системы';
			}
			$stage = $row['stage'];
			$stage_date = $row['stage_date'];
			$recset->closeCursor();
		}
//				
// Если есть ошибки - можно уже закончить
//		
		if( $errdata ) throw new Exception($errdata, 1);
		
// par_build_id  build_name
		if( $build_name == '' ) $errdata .= ($errdata?'<br>':'').'- Не указан шифр объекта.';
		elseif( !ctype_digit( $par_build_id ) ) 
			$errdata .= ($errdata?'<br>':'').'- Не указан идентификатор объекта.';
		else {
// Проверяем наличие обьекта в справочнике
			$recset = $db->query('SELECT build_id FROM builds WHERE build_id = '.$db->quote($par_build_id));                  
			$row = $recset->fetch(PDO::FETCH_ASSOC);
			if( !$row ) {
				$errdata .= ($errdata?'<br>':'').'- Неправильно указан идентификатор объекта.';
			}
			$recset->closeCursor();
		}

// height			
		if( $height == '' || $height == '0' ) $errdata .= ($errdata?'<br>':'')."- Не указана высота мачты.";
		else {
			if( !ctype_digit( $height ) )
				$errdata .= ($errdata?'<br>':'')."- Неправильно указана высота мачты.";
		}
			
// poyt
		if( $poyt == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана дата PO YT.";
		elseif( ( $poyt = Tools::check_date($poyt) ) === false )
			$errdata .= ($errdata?'<br>':'')."- Дата PO YT указана неправильно.";

// scsr
		if( $scsr == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана дата SCSR.";
		elseif( ( $scsr = Tools::check_date($scsr) ) === false )
			$errdata .= ($errdata?'<br>':'')."- Дата SCSR указана неправильно.";

// los
		if( $los == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана дата LOS.";
		elseif( ( $los = Tools::check_date($los) ) === false )
			$errdata .= ($errdata?'<br>':'')."- Дата LOS указана неправильно.";

// cwsr
		if( $cwsr == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана дата CWSR.";
		elseif( ( $cwsr = Tools::check_date($cwsr) ) === false )
			$errdata .= ($errdata?'<br>':'')."- Дата CWSR указана неправильно.";

// start_cw
		if( $start_cw == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана дата 'Старт CW'.";
		elseif( ( $start_cw = Tools::check_date($start_cw) ) === false )
			$errdata .= ($errdata?'<br>':'')."- Дата 'Старт CW' указана неправильно.";

// finish_cw
		if( $finish_cw == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана дата 'Финиш CW'.";
		elseif( ( $finish_cw = Tools::check_date($finish_cw) ) === false )
			$errdata .= ($errdata?'<br>':'')."- Дата 'Финиш CW' указана неправильно.";

// loctype			
		if( $loctype == '' || $loctype == '0' ) $errdata .= ($errdata?'<br>':'')."- Не указан тип расположения.";
		else {
			if( !ctype_digit( $loctype ) || $loctype < 1 || $loctype > 3 )
				$errdata .= ($errdata?'<br>':'')."- Неправильно указан тип расположения.";
		}

// perm01_date		
		if( $perm01_date == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана 'Дата решения 1'.";
		elseif( ( $perm01_date = Tools::check_date($perm01_date) ) === false )
			$errdata .= ($errdata?'<br>':'')."- 'Дата решения 1' указана неправильно.";

// perm02_date		
		if( $perm02_date == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана 'Дата решения 2'.";
		elseif( ( $perm02_date = Tools::check_date($perm02_date) ) === false )
			$errdata .= ($errdata?'<br>':'')."- 'Дата решения 2' указана неправильно.";

// perm03_date		
		if( $perm03_date == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана 'Дата решения 3'.";
		elseif( ( $perm03_date = Tools::check_date($perm03_date) ) === false )
			$errdata .= ($errdata?'<br>':'')."- 'Дата решения 3' указана неправильно.";

// rent		
		if( $rent == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана 'Дата договора аренды'.";
		elseif( ( $rent = Tools::check_date($rent) ) === false )
			$errdata .= ($errdata?'<br>':'')."- 'Дата договора аренды' указана неправильно.";

// decl01		
		if( $decl01 == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана дата 'Декларация 1'.";
		elseif( ( $decl01 = Tools::check_date($decl01) ) === false )
			$errdata .= ($errdata?'<br>':'')."- Дата 'Декларация 1' указана неправильно.";

// decl02		
		if( $decl02 == '' ) $errdata .= ($errdata?'<br>':'')."- Не указана дата 'Декларация 2'.";
		elseif( ( $decl02 = Tools::check_date($decl02) ) === false )
			$errdata .= ($errdata?'<br>':'')."- Дата 'Декларация 2' указана неправильно.";

//				
// Если есть ошибки - можно уже закончить
//		
		if( $errdata ) throw new Exception($errdata, 1);
		
// Может быть объект с указаным именем уже существует
		$sqlreq =	'SELECT build_name FROM parcel '.
					'INNER JOIN builds ON builds.build_id = parcel.par_build_id '.
					'WHERE par_build_id = '.$db->quote($par_build_id).' AND '.
							'par_id != '.$db->quote($par_id);
							
		$recset = $db->query( $sqlreq );
		
		$row = $recset->fetch(PDO::FETCH_ASSOC);
		if( $row ) {
			throw new Exception('Данные по объекту "'.$row['build_name'].'" уже присутствуют.', 1);
        }    
		$recset->closeCursor();

// Пишем данные
        $sqlreq =   'UPDATE parcel SET '.
						'par_build_id = '. $db->quote($par_build_id).', '.
						'height = '.$db->quote($height).", ".
						'poyt = '.	$db->quote($poyt).", ".
						'scsr = '.	$db->quote($scsr).", ".
						'los = '.	$db->quote($los).", ".
						'cwsr = '.	$db->quote($cwsr).", ".
						'start_cw = '.	 $db->quote($start_cw).", ".
						'finish_cw = '.  $db->quote($finish_cw).", ".
						'loctype = '.	 $db->quote($loctype).", ".
						'perm01_date = '.$db->quote($perm01_date).", ".
						'perm02_date = '.$db->quote($perm02_date).", ".
						'perm03_date = '.$db->quote($perm03_date).", ".
						'rent = '.	 $db->quote($rent).", ".
						'decl01 = '. $db->quote($decl01).", ".
						'decl02 = '. $db->quote($decl02).", ".
						'stage = '.  $db->quote($stage).", ".
						'stage_date = '. $db->quote($stage_date).", ".
						'par_comment = '.$db->quote($par_comment).", ".
						'par_user_id = '.$db->quote($par_user_id)." ".
                    'WHERE par_id = '.$db->quote($par_id);
												
		$db->exec($sqlreq);
    }
	catch (PDOException $e) {
		$errcode = 1;
//		$errmess = ERR_M::DATABASE_ERROR;
		$errmess = $e->getMessage();
	}
    catch ( Exception $e ) {
		$errcode = $e->getCode();
		$errmess = $e->getMessage();
	}

	return array('errcode'=>$errcode,'errmess'=>$errmess);
  }
*/  
  
  public function delete() {
    $errmess = "";
	$errcode = 0;
		
    $par_ids = (isset($_REQUEST['id']) && $_REQUEST['id'] != '') ?
        explode(",", $_REQUEST["id"], 100) : array();

    try
    {
// Только зарегистрированные пользователи могут удалять данные
		if( !isset($_SESSION['user_id']) || $_SESSION['user_id'] == 0 )
			throw new Exception(ERR_M::TIMEOUT_ERROR, 999);

// Есть ли разрешение на удаление хоть какой либо записи
		$rwd = $_SESSION['priv']->parcel->rwd;
		if( ($rwd & PERM_BITS::DELETE_ANY) == 0 ) throw new Exception(ERR_M::DATA_OPER_DISABLED, 99);
		
        if (!Tools::is_numeric_array( $par_ids ))
			throw new Exception(ERR_M::PROTOCOL_ERROR, 1);
        
		$par_id_list = implode(',', $par_ids);

// Открываем базу данных
		$db = App::me()->dbOpen();	

// Есть ли разрешение на удаление этих записей
		if( $rwd & PERM_BITS::DELETE_OTH ) $where = '1 = 1';
		elseif( $rwd & PERM_BITS::DELETE_GRP ) 
			$where = 'par_user_id IN (SELECT user_id FROM users WHERE cat_id = '.$_SESSION['cat_id'].')';
		elseif( $rwd & PERM_BITS::DELETE_OWN ) $where = 'par_user_id = '.$_SESSION['user_id'];
		else $where = '1 = 0';
		$where .= ' AND par_id IN ('.$par_id_list.')';
		
		$sqlreq = 'SELECT COUNT(*) AS count FROM parcel WHERE '.$where;
		$recset = $db->query( $sqlreq );		
		$row = $recset->fetch(PDO::FETCH_ASSOC);
		if( $row['count'] != count($par_ids) ) {
			throw new Exception(ERR_M::DATA_OWNER_DISABLED, 99);
        }    
		$recset->closeCursor();
		
// Удаляем по одному, нужно удалять и фото
		foreach( $par_ids as $par_id ) { 
// Получим имя обьекта
			$sqlreq =	'SELECT build_name FROM parcel '.
						'INNER JOIN builds ON builds.build_id = parcel.par_build_id '.
						'WHERE par_id = '.$db->quote($par_id);
			$recset = $db->query( $sqlreq );
			$row = $recset->fetch(PDO::FETCH_ASSOC);
			if( ! $row ) {
				throw new Exception('Данные по объекту не найдены.', 1);
			}
			$build_name = $row['build_name'];
			$recset->closeCursor();
			
// Удаляем запись
			$sqlreq = "DELETE FROM parcel WHERE par_id = ".$db->quote($par_id);
			$db->exec($sqlreq);
		
// Удаляем сканы
			$bname = preg_replace( '/[^а-яіїa-z0-9]/u', '', mb_strtolower( $build_name, 'UTF-8') );
			$dr = App::me()->basePath. DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'docs' . DIRECTORY_SEPARATOR;
			
			if( is_file( $dr.$bname.'_perm01.pdf' ) ) unlink($dr.$bname.'_perm01.pdf');
			if( is_file( $dr.$bname.'_perm02.pdf' ) ) unlink($dr.$bname.'_perm02.pdf');
			if( is_file( $dr.$bname.'_perm03.pdf' ) ) unlink($dr.$bname.'_perm03.pdf');
		}
	}
	catch (PDOException $e) {
		$errcode = 1;
		$errmess = ERR_M::DATABASE_ERROR;
	}
    catch ( Exception $e ) {
		$errcode = $e->getCode();
		$errmess = $e->getMessage();
	}

	return array('errcode'=>$errcode,'errmess'=>$errmess);
  }


  public function loadnotes() {
  
    $errmess = "";
	$errcode = 0;
	$txt_text = '';
		
    $build_id = (isset($_REQUEST['build_id']) && is_numeric($_REQUEST['build_id'])) ? $_REQUEST['build_id'] : '';

    try
    {
// Только зарегистрированные пользователи могут удалять данные
		if( !isset($_SESSION['user_id']) || $_SESSION['user_id'] == 0 )
			throw new Exception(ERR_M::TIMEOUT_ERROR, 999);

        if ( $build_id == '' )
			throw new Exception(ERR_M::PROTOCOL_ERROR, 1);
        
// Открываем базу данных
		$db = App::me()->dbOpen();	

// Читаем данные
		$sqlreq =	'SELECT txt_text FROM texts '.
					'WHERE txt_owner_id = (SELECT tab_id FROM tables WHERE tab_name = "parcel") '.
					'AND txt_orec_id = '.$db->quote($build_id);
							
		$recset = $db->query( $sqlreq );
		
		$row = $recset->fetch(PDO::FETCH_ASSOC);
		if( $row ) {
			$txt_text = $row['txt_text'];
        }    
		$recset->closeCursor();

	}
	catch (PDOException $e) {
		$errcode = 1;
		$errmess = ERR_M::DATABASE_ERROR;
	}
    catch ( Exception $e ) {
		$errcode = $e->getCode();
		$errmess = $e->getMessage();
	}

	return array('errcode'=>$errcode,'errmess'=>$errmess, 'data'=>$txt_text);
  }

  
  public function savenotes() {
  
    $errmess = "";
	$errcode = 0;
	$all_text = '';
		
    $build_id = (isset($_REQUEST['build_id']) && is_numeric($_REQUEST['build_id'])) ? $_REQUEST['build_id'] : '';
    $txt_text = isset($_REQUEST['notes']) ? trim(strip_tags($_REQUEST['notes'])) : '';

    try
    {
// Только зарегистрированные пользователи могут удалять данные
		if( !isset($_SESSION['user_id']) || $_SESSION['user_id'] == 0 )
			throw new Exception(ERR_M::TIMEOUT_ERROR, 999);

		$txt_user_id = $_SESSION['user_id'];
		
        if ( $build_id == '' )
			throw new Exception(ERR_M::PROTOCOL_ERROR, 1);
        
// Открываем базу данных
		$db = App::me()->dbOpen();	

// Читаем данные
		$sqlreq =	'SELECT txt_text FROM texts '.
					'WHERE txt_owner_id = (SELECT tab_id FROM tables WHERE tab_name = "parcel") '.
					'AND txt_orec_id = '.$db->quote($build_id);
							
		$recset = $db->query( $sqlreq );
		
		$row = $recset->fetch(PDO::FETCH_ASSOC);
		if( $row ) {
			$all_text = $row['txt_text'];
        }    
		$recset->closeCursor();
		
		if( $txt_text ) {
			$all_text = $all_text."\n\n-- ".$_SESSION['full_name']." ".date('d.m.Y H:i:s')." --\n".$txt_text;
			$slen = mb_strlen( $all_text, 'UTF-8' );
			if( $slen > 10000 )
				$all_text = substr( $all_text, $slen-10000, $slen, 'UTF-8' );
				
			$sqlreq =	'REPLACE INTO texts SET '.
						'txt_owner_id = (SELECT tab_id FROM tables WHERE tab_name = "parcel"), '.
						'txt_orec_id = '.$db->quote($build_id).', '.
						'txt_text = '.$db->quote($all_text).', '.
						'txt_user_id = '.$db->quote($txt_user_id);
							
			$db->exec( $sqlreq );
		}

	}
	catch (PDOException $e) {
		$errcode = 1;
		$errmess = ERR_M::DATABASE_ERROR;
	}
    catch ( Exception $e ) {
		$errcode = $e->getCode();
		$errmess = $e->getMessage();
	}

	return array('errcode'=>$errcode,'errmess'=>$errmess, 'data'=>$all_text);
  }

// 00 - not view & not edit
// X1 - view, 1X - edit
  private function set_edit_status( &$edit_status, $par_num, $status ) {
	$ed = ( $status & 2 ) ? '1' : '0';
	$vw = ( $status & 1 ) ? '1' : '0';
	$edit_status = substr_replace( $edit_status, $vw . $ed, 2 * $par_num, 2 );
  }
  
// 1day = 1 * 24 * 60 * 60 = 86400s.
  private function gen_edit_status( $row ) {
	$stage = $row['stage'];
	$stage_date = $row['stage_date'];
	$iv = Tools::how_many('sec', $stage_date) < $this->bounce_time; 
	$edit_status = str_repeat('00',32);
	switch( $stage ) {
		case 0:		// Создание новой записи
			$this->set_edit_status( $edit_status, BUILD_NAME, SET_EDIT | SET_VIEW );
			$this->set_edit_status( $edit_status, BUILD_ADDRESS, SET_VIEW );
			break;
		case 1:		// Подготовительный этап. Определение технических условий и типа землеотведения.
			if( $iv ) $this->set_edit_status( $edit_status, BUILD_NAME, SET_EDIT | SET_VIEW );
			else $this->set_edit_status( $edit_status, BUILD_NAME, SET_VIEW );
			$this->set_edit_status( $edit_status, BUILD_ADDRESS, SET_VIEW );
			
			$this->set_edit_status( $edit_status, BUILD_HIGHT, SET_EDIT | SET_VIEW );
			$this->set_edit_status( $edit_status, POYT, SET_EDIT | SET_VIEW );
			$this->set_edit_status( $edit_status, SCSR, SET_EDIT | SET_VIEW );
			$this->set_edit_status( $edit_status, LOS, SET_EDIT | SET_VIEW );
			$this->set_edit_status( $edit_status, CWSR, SET_EDIT | SET_VIEW );
			$this->set_edit_status( $edit_status, LOC_TYPE, SET_EDIT | SET_VIEW );
			break;
		case 2:		// Решение 1
			$this->set_edit_status( $edit_status, BUILD_NAME, SET_VIEW );
			$this->set_edit_status( $edit_status, BUILD_ADDRESS, SET_VIEW );
			if( $iv ) {
				$this->set_edit_status( $edit_status, BUILD_HIGHT, SET_EDIT | SET_VIEW );
				$this->set_edit_status( $edit_status, POYT, SET_EDIT | SET_VIEW );
				$this->set_edit_status( $edit_status, SCSR, SET_EDIT | SET_VIEW );
				$this->set_edit_status( $edit_status, LOS, SET_EDIT | SET_VIEW );
				$this->set_edit_status( $edit_status, CWSR, SET_EDIT | SET_VIEW );
				$this->set_edit_status( $edit_status, LOC_TYPE, SET_EDIT | SET_VIEW );
			}
			$this->set_edit_status( $edit_status, PERM01_DATE, SET_EDIT | SET_VIEW );
			break;
		case 3:		// Решение 2
			$this->set_edit_status( $edit_status, BUILD_NAME, SET_VIEW );
			$this->set_edit_status( $edit_status, BUILD_ADDRESS, SET_VIEW );
			if( $iv ) {
				$this->set_edit_status( $edit_status, PERM01_DATE, SET_EDIT | SET_VIEW );
			}
			$this->set_edit_status( $edit_status, PERM02_DATE, SET_EDIT | SET_VIEW );
			break;
		case 4:		// Решение 3
			$this->set_edit_status( $edit_status, BUILD_NAME, SET_VIEW );
			$this->set_edit_status( $edit_status, BUILD_ADDRESS, SET_VIEW );
			if( $iv ) {
				if( $row['loctype'] == 2 )
					$this->set_edit_status( $edit_status, PERM02_DATE, SET_EDIT | SET_VIEW );
				else
					$this->set_edit_status( $edit_status, PERM01_DATE, SET_EDIT | SET_VIEW );					
			}
			$this->set_edit_status( $edit_status, PERM03_DATE, SET_EDIT | SET_VIEW );
			break;
		case 5:		// Договор аренды
			$this->set_edit_status( $edit_status, BUILD_NAME, SET_VIEW );
			$this->set_edit_status( $edit_status, BUILD_ADDRESS, SET_VIEW );
			if( $iv ) {
				$this->set_edit_status( $edit_status, PERM03_DATE, SET_EDIT | SET_VIEW );
			}
			$this->set_edit_status( $edit_status, RENT_DATE, SET_EDIT | SET_VIEW );
			break;
		case 6:		// Декларация 1
			$this->set_edit_status( $edit_status, BUILD_NAME, SET_VIEW );
			$this->set_edit_status( $edit_status, BUILD_ADDRESS, SET_VIEW );
			if( $iv ) {
				$this->set_edit_status( $edit_status, RENT_DATE, SET_EDIT | SET_VIEW );
			}
			$this->set_edit_status( $edit_status, DECL01_DATE, SET_EDIT | SET_VIEW );
			break;
		case 7:		// Декларация 2
			$this->set_edit_status( $edit_status, BUILD_NAME, SET_VIEW );
			$this->set_edit_status( $edit_status, BUILD_ADDRESS, SET_VIEW );
			if( $iv ) {
				$this->set_edit_status( $edit_status, DECL01_DATE, SET_EDIT | SET_VIEW );
			}
			$this->set_edit_status( $edit_status, DECL02_DATE, SET_EDIT | SET_VIEW );
			break;
		case 8:		// Декларация 2
			if( $iv ) {
				$this->set_edit_status( $edit_status, BUILD_NAME, SET_VIEW );
				$this->set_edit_status( $edit_status, BUILD_ADDRESS, SET_VIEW );
				$this->set_edit_status( $edit_status, DECL02_DATE, SET_EDIT | SET_VIEW );
			}
			break;
	}
	return $edit_status;
  }
  
  private function set_alert_status( &$alert_status, $par_num ) {
	$alert_status = substr_replace( $alert_status, '1', $par_num, 1 );
  }
  
  private function gen_alert_status( $row ) {
	$alert_status = str_repeat('0',32);
	switch( $row['stage'] ) {
		case 0:		// Создание новой записи
			break;
		case 1:		// Подготовительный этап. Определение технических условий и типа землеотведения.
			$control_date = $row['stage_date'];
			$aa = Tools::how_many( 'sec', $control_date );
			if( Tools::how_many( 'sec', $control_date ) > $this->stage_timeout[1] ) {
				if( !$row['height'] ) $this->set_alert_status( $alert_status, BUILD_HIGHT );
				if( !$row['scsr'] ) $this->set_alert_status( $alert_status, SCSR );
				if( !$row['los'] ) $this->set_alert_status( $alert_status, LOS );
				if( !$row['cwsr'] ) $this->set_alert_status( $alert_status, CWSR );
				if( !$row['loctype'] ) $this->set_alert_status( $alert_status, LOC_TYPE );
			}
			break;
		case 2:		// Решение 1
			$control_date = $row['cwsr'];
			if( Tools::how_many( 'sec', $control_date ) > $this->stage_timeout[2] ) {
				if( !$row['perm01_date'] ) $this->set_alert_status( $alert_status, PERM01_DATE );
			}
			break;
		case 3:		// Решение 2
			$control_date = $row['perm01_date'];
			if( Tools::how_many( 'sec', $control_date ) > $this->stage_timeout[3] ) {
				if( !$row['perm02_date'] ) $this->set_alert_status( $alert_status, PERM02_DATE );
			}
			break;
		case 4:		// Решение 3
			if( $row['loctype'] == 1 ) $control_date = $row['perm01_date'];
			else $control_date = $row['perm02_date'];
			
			if( Tools::how_many( 'sec', $control_date ) > $this->stage_timeout[4] ) {
				if( !$row['perm03_date'] ) $this->set_alert_status( $alert_status, PERM03_DATE );
			}
			break;
		case 5:		// Договор аренды
			$control_date = $row['perm03_date'];
			if( Tools::how_many( 'sec', $control_date ) > $this->stage_timeout[5] ) {
				if( !$row['rent'] ) $this->set_alert_status( $alert_status, RENT_DATE );
			}
			break;
		case 6:		// Декларация 1
			$control_date = $row['rent'];
			if( Tools::how_many( 'sec', $control_date ) > $this->stage_timeout[6] ) {
				if( !$row['decl01'] ) $this->set_alert_status( $alert_status, DECL01_DATE );
			}
			break;
		case 7:		// Декларация 2
			$control_date = $row['decl01'];
			if( Tools::how_many( 'sec', $control_date ) > $this->stage_timeout[7] ) {
				if( !$row['decl02'] ) $this->set_alert_status( $alert_status, DECL02_DATE );
			}
			break;
		default: break;
	}
	return $alert_status;
  }

  public function doc_down() {
  
// Путь к архиву
	$dr = App::me()->basePath. DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'docs' . DIRECTORY_SEPARATOR;
	$blankImg = $dr . 'blank.pdf';

	while( true ) {
// Только зарегистрированные пользователи могут видеть данные
		if( !isset($_SESSION['user_id']) || $_SESSION['user_id'] == 0 ) {
			$fname = $blankImg;
			break;
		}

// Проверяем данные
		$img = isset($_REQUEST["img"]) ? trim(strip_tags($_REQUEST["img"])) : '';
    
		$fname = $dr.$img.'.pdf';
		if( !is_file( $fname ) )
			$fname = $blankImg;
			
		break;
	}
 
	header("Expires: Wed, 19 Nov 2008 19:19:19 GMT");
	header("Cache-Control: no-store, no-cache, must-revalidate");
	header("Content-Type: application/pdf");
//	header("Content-Disposition: inline; filename=\"".basename($fname)."\";" );
//	header('Pragma: public' );
    header("Content-Length: ".filesize($fname)); 
	readfile($fname);
  }
  
  
  public function doc_upl() {
	$errcode = 0;
	$errmess = '';
	
	if( !isset($_FILES['files']['tmp_name'][0]) || !is_file($_FILES['files']['tmp_name'][0]) )
		return array('errcode'=>'Ошибка загрузки файла','errmess'=>1 );

	$f = $_FILES['files'];
	
    try
    {
// Только зарегистрированные пользователи могут видеть данные
		if( !isset($_SESSION['user_id']) || $_SESSION['user_id'] == 0 )
			throw new Exception(ERR_M::TIMEOUT_ERROR, 999);

// Есть ли разрешение на изменение чьей либо записи
		$rwd = $_SESSION['priv']->parcel->rwd;
		if( ($rwd & PERM_BITS::WRITE_ANY) == 0 ) throw new Exception(ERR_M::DATA_OPER_DISABLED, 99);
		
// Проверяем успешно ли прошла загрузка и тот ли это файл
		$doc = '';
		$ok = false;
		if( $f['name'][0] !== '' ) {
			list( $t1, $t2 ) = explode('/',$f['type'][0]); 
			if( $f['error'][0] === 0 && $f['size'][0] < 8000000 && $t1 == 'application' || $t2 == 'pdf' ) {
				$doc = $f['tmp_name'][0];
				$ok = true;
			}
		}
		if( !$ok ) throw new Exception('Ошибка загрузки файла документа', 1);

// Проверяем данные
		$img = isset($_POST['img']) ? trim(strip_tags($_POST['img'])) : '';
		list( $aa, $field ) = explode('_',$img);
		switch( $field ) {
			case 'perm01': $field = 'perm01_date'; break;
			case 'perm02': $field = 'perm02_date'; break;
			case 'perm03': $field = 'perm03_date'; break;
			default: $field = ''; break;
		}
		$par_id = isset($_POST['par_id']) ? trim(strip_tags($_POST['par_id'])) : '';
		if( !$img || !$field || !ctype_digit($par_id) ) throw new Exception(ERR_M::PROTOCOL_ERROR, 1);
   
// Открываем базу данных
		$db = App::me()->dbOpen();	

// Есть ли разрешение на апдейт этой записи
		if( $rwd & PERM_BITS::WRITE_OTH ) $where = '1 = 1';
		elseif( $rwd & PERM_BITS::WRITE_GRP ) 
			$where = 'par_user_id IN (SELECT user_id FROM users WHERE cat_id = '.$_SESSION['cat_id'].')';
		elseif( $rwd & PERM_BITS::WRITE_OWN ) $where = 'par_user_id = '.$_SESSION['user_id'];
		else $where = '1 = 0';
		$where .= ' AND par_id = '.$db->quote($par_id);
		
		$sqlreq = 'SELECT COUNT(*) AS count FROM parcel WHERE '.$where.' LIMIT 1';
		$recset = $db->query( $sqlreq );		
		$row = $recset->fetch(PDO::FETCH_ASSOC);
		if( !$row['count'] ) {
			throw new Exception(ERR_M::DATA_OWNER_DISABLED, 99);
        }    
		$recset->closeCursor();
		
// Читаем данные
		$sqlreq =	'SELECT '.$field.' FROM parcel WHERE par_id = '.$db->quote($par_id);							
		$recset = $db->query( $sqlreq );
		$row = $recset->fetch(PDO::FETCH_ASSOC);
		$ok = $row && !is_null($row[$field]) && Tools::check_date($row[$field]);
		$recset->closeCursor();
		if( !$ok ) throw new Exception(ERR_M::PROTOCOL_ERROR, 1);
		
// Путь к фото-архиву
		$dr = App::me()->basePath. DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'docs' . DIRECTORY_SEPARATOR;

// Затем, перемещаем в него загруженный файл фото.
		move_uploaded_file( $doc, $dr.$img.'.pdf' );
 
    }
	catch (PDOException $e) {
		unlink($f['tmp_name'][0]);
		$errcode = 1;
		$errmess = ERR_M::DATABASE_ERROR;
	}
    catch ( Exception $e ) {
		unlink($f['tmp_name'][0]);
		$errcode = $e->getCode();
		$errmess = $e->getMessage();
	}
 
	return array('errcode'=>$errcode,'errmess'=>$errmess );
  }
  
  
  public function doc_del() {
    $errmess = "";
	$errcode = 0;
		
// Путь к фото-архиву
	$dr = App::me()->basePath. DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'docs' . DIRECTORY_SEPARATOR;

    try
    {
// Только зарегистрированные пользователи могут удалять данные
		if( !isset($_SESSION['user_id']) || $_SESSION['user_id'] == 0 )
			throw new Exception(ERR_M::TIMEOUT_ERROR, 999);

// Проверяем данные
		$par_id = isset($_POST['par_id']) ? trim(strip_tags($_POST['par_id'])) : '';
		if( !$par_id || !ctype_digit($par_id) ) throw new Exception(ERR_M::PROTOCOL_ERROR, 1);
   
		$img = isset($_REQUEST["img"]) ? trim(strip_tags($_REQUEST["img"])) : '';
		if( !$img ) throw new Exception(ERR_M::PROTOCOL_ERROR, 1);
		
// Есть ли разрешение на изменение чьей либо записи
		$rwd = $_SESSION['priv']->parcel->rwd;
		if( ($rwd & PERM_BITS::WRITE_ANY) == 0 ) throw new Exception(ERR_M::DATA_OPER_DISABLED, 99);
		
// Открываем базу данных
		$db = App::me()->dbOpen();	

// Есть ли разрешение на апдейт этой записи
		if( $rwd & PERM_BITS::WRITE_OTH ) $where = '1 = 1';
		elseif( $rwd & PERM_BITS::WRITE_GRP ) 
			$where = 'par_user_id IN (SELECT user_id FROM users WHERE cat_id = '.$_SESSION['cat_id'].')';
		elseif( $rwd & PERM_BITS::WRITE_OWN ) $where = 'par_user_id = '.$_SESSION['user_id'];
		else $where = '1 = 0';
		$where .= ' AND par_id = '.$db->quote($par_id);
		
		$sqlreq = 'SELECT COUNT(*) AS count FROM parcel WHERE '.$where.' LIMIT 1';
		$recset = $db->query( $sqlreq );		
		$row = $recset->fetch(PDO::FETCH_ASSOC);
		if( !$row['count'] ) {
			throw new Exception(ERR_M::DATA_OWNER_DISABLED, 99);
        }    
		$recset->closeCursor();
		
// Удаляем файл		
		$fname = $dr.$img.'.pdf';
		if( !is_file( $fname ) ) throw new Exception('Документ не найден', 1);
		unlink( $fname );
	}
	catch (PDOException $e) {
		unlink($f['tmp_name'][0]);
		$errcode = 1;
		$errmess = ERR_M::DATABASE_ERROR;
	}
    catch ( Exception $e ) {
		$errcode = $e->getCode();
		$errmess = $e->getMessage();
	}

	return array('errcode'=>$errcode,'errmess'=>$errmess);
  }

}
?>